package dynamic

import (
	"github.com/gin-gonic/gin"
	"time"
	service "vrcm/src/vrcm/app/admin/service/dynamic"
	"vrcm/src/vrcm/app/consts"
	"vrcm/src/vrcm/app/do/request"
	"vrcm/src/vrcm/common/apis"
)

type Dynamic struct {
	apis.Api
}

// DynamicList 列表
func (this Dynamic) DynamicList(c *gin.Context) {
	var (
		req request.DynamicList
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.DynamicList(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicInfo 列表
func (this Dynamic) DynamicInfo(c *gin.Context) {
	var (
		req request.DynamicInfo
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.DynamicInfo(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicCreate 创建
func (this Dynamic) DynamicCreate(c *gin.Context) {
	var (
		req request.DynamicEdit
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	if req.DynamicType == consts.DynamicDomainType && len(req.Domains) == 0 {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	if len(req.Rules) == 0 || len(req.OriginStations) == 0 || req.TenantId == "" ||
		req.Account == "" || req.Position == "" || req.SchedulePolicy == "" ||
		req.ExpirationTime <= time.Now().Unix() {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	var (
		httpC, httpsC int
	)
	for _, val := range req.Rules {
		if httpsC > 1 || httpC > 1 {
			this.Error(apis.DynamicRuleErr.Code, nil, apis.DynamicRuleErr.Msg)
			return
		}
		if val.Protocol == consts.ProtocolHttp {
			httpC++
		}
		if val.Protocol == consts.ProtocolHttps {
			httpsC++
		}
	}
	data, err := s.DynamicCreate(c, req)
	if err != nil {
		this.Error(apis.DynamicEditErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicUpdate 更新
func (this Dynamic) DynamicUpdate(c *gin.Context) {
	var (
		req request.DynamicEdit
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	if req.DynamicType == consts.DynamicDomainType && len(req.Domains) == 0 {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	if len(req.Rules) == 0 || len(req.OriginStations) == 0 || req.TenantId == "" ||
		req.Account == "" || req.Id <= 0 || req.Position == "" || req.SchedulePolicy == "" ||
		req.ExpirationTime <= time.Now().Unix() {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	var (
		httpC, httpsC  int
		layerMap       = make(map[string]struct{})
		layerOriginMap = make(map[string]struct{})
	)
	for _, val := range req.Rules {
		if httpsC > 1 || httpC > 1 {
			this.Error(apis.DynamicRuleErr.Code, nil, apis.DynamicRuleErr.Msg)
			return
		}
		if val.Protocol == consts.ProtocolTCP || val.Protocol == consts.ProtocolUdp {
			// dynamic
			if _, ok := layerMap[val.Protocol+val.DynamicPort]; ok {
				this.Error(apis.DynamicLayerPortErr.Code, nil, apis.DynamicLayerPortErr.Msg)
				return
			} else {
				layerMap[val.Protocol+val.DynamicPort] = struct{}{}
			}
			// origin
			if _, ok := layerOriginMap[val.Protocol+val.OriginPort]; ok {
				this.Error(apis.DynamicLayerOriginPortErr.Code, nil, apis.DynamicLayerOriginPortErr.Msg)
				return
			} else {
				layerOriginMap[val.Protocol+val.OriginPort] = struct{}{}
			}
		}
		if val.Protocol == consts.ProtocolHttp {
			httpC++
		}
		if val.Protocol == consts.ProtocolHttps {
			httpsC++
		}
	}
	var (
		IsMaster bool
	)
	for _, val := range req.OriginStations {
		if val.IsMaster == consts.IsMaster {
			IsMaster = true
			break
		}
	}
	if !IsMaster {
		this.Error(apis.IsMaster.Code, nil, apis.IsMaster.Msg)
		return
	}
	data, err := s.DynamicUpdate(c, req)
	if err != nil {
		this.Error(apis.DynamicEditErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

func (this Dynamic) DynamicUpdateNotReqNgvsa(c *gin.Context) {
	var (
		req request.DynamicEdit
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.DynamicUpdateNotReqNgvsa(c, req)
	if err != nil {
		this.Error(apis.DynamicEditErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicDelete 删除
func (this Dynamic) DynamicDelete(c *gin.Context) {
	var (
		req request.DynamicDel
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	if req.Id <= 0 {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	if req.DelType != consts.ActionDel && req.DelType != consts.ActionTrans {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	data, err := s.DynamicDelete(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicStopOrRecover 启用或禁用
func (this Dynamic) DynamicStopOrRecover(c *gin.Context) {
	var (
		req request.DynamicStop
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	if req.Id <= 0 {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	data, err := s.DynamicStopOrRecover(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicGetPort 获取端口
func (this Dynamic) DynamicGetPort(c *gin.Context) {
	var (
		req request.DynamicGetPort
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.DynamicGetPort(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

func (this Dynamic) DynamicCheckPort(c *gin.Context) {
	var (
		req request.DynamicCheckPort
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	if req.Protocol == "" || req.Ports == "" {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	data, err := s.DynamicCheckPort(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicUInstName 更新实例名称
func (this Dynamic) DynamicUInstName(c *gin.Context) {
	var (
		req request.DynamicUInstName
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.DynamicUInstName(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicPackageList 订单列表
func (this Dynamic) DynamicPackageList(c *gin.Context) {
	var (
		req request.DynamicPackageList
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.DynamicPackageList(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicPackageInfo 订单详情
func (this Dynamic) DynamicPackageInfo(c *gin.Context) {
	var (
		req request.DynamicPackageInfo
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.DynamicPackageInfo(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

// DynamicDomainList 历史加速域名列表
func (this Dynamic) DynamicDomainList(c *gin.Context) {
	var (
		req request.DynamicDomainList
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.DynamicDomainList(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

func (this Dynamic) DynamicDealRecord(c *gin.Context) {
	var (
		req request.DynamicDealRecord
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	if req.PackageId == "" || req.Action == "" || req.TenantId == "" {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	data, err := s.DynamicDealRecord(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

func (this *Dynamic) AreaList(c *gin.Context) {
	var (
		req request.DynamicDealRecord
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.AreaList(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

func (this *Dynamic) TopoArea(c *gin.Context) {
	var (
		req request.DynamicDealRecord
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.TopoArea(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

func (this *Dynamic) SpecialTenantList(c *gin.Context) {
	var (
		req request.SpecialTenantList
		s   = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		Bind(&req).
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	if req.TenantId == "" || req.ProtocolType == "" {
		this.Error(apis.DynamicParamErr.Code, nil, apis.DynamicParamErr.Msg)
		return
	}
	data, err := s.SpecialTenantList(c, req)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

func (this *Dynamic) VcfnCnameList(c *gin.Context) {
	var (
		s = service.DynamicServer{}
	)
	err := this.MakeContext(c).
		MakeOrm().
		MakeService(&s.Service).
		Errors
	if err != nil {
		this.Logger.Error(err)
		this.Error(apis.InternalError.Code, err, err.Error())
		return
	}
	data, err := s.VcfnCnameList(c)
	if err != nil {
		this.Error(apis.DynamicErr.Code, err, err.Error())
		return
	}
	this.ok(data)
}

func (this Dynamic) ok(d interface{}) {
	this.OK(d, "success")
}
